#include <stdlib.h>
#include <burst_kernel.h>

#define follow(s, ch, ifyes, ifno) ((*(s) == (ch)) ? (++(s), (ifyes)) : (ifno))

u64 now_file_pointer = 0;
u64 last_file_pointer = 0;
u8 *file_buf;
u64 file_size = 0;
u_int file_fd;

int lexer_init(char *stream, int len)
{
	now_file_pointer = last_file_pointer = 0;
	file_buf = (u8 *)stream;
	file_size = len;
	return 1;
}

void lexer_reset()
{
	now_file_pointer = 0;
	last_file_pointer = 0;
}

static void lexer_skip_white(int *param_pointer)
{
	u8 buf;
	for(;;) {
		buf = file_buf[*param_pointer];
		if(buf != '\n' && buf != '\r' && buf != ' ' && buf != '\t') {
			return;
		}
		*param_pointer ++;
	}
}

static int lexer_get_next_pointer(int origin, int word_length)
{
	return origin + word_length + 1;
}

static int lexer_get_token_len(int param_pointer)
{
	u8 buf;
	int quota = 0;
	int tmp_file_pointer = param_pointer;
	int length_get = 0;
	for(;;) {
		buf = file_buf[tmp_file_pointer];
		switch(buf) {
		case '"':
			if(!quota) {
				if(length_get) {
					return length_get;
				}
				quota = 1;
				break;
			}
			return length_get;
		case ' ':
			if(!quota)
				return length_get;
		default:
			tmp_file_pointer ++;
			length_get ++;
			break;
		}
	}
}

int lexer_get_token(u64 *value, char **string, int *len)
{
	int token_len = 0;
	int i;
	int ret = BADTOK;
	int tmp_file_pointer = now_file_pointer;
	u8 buf = file_buf[tmp_file_pointer];
	lexer_skip_white(&tmp_file_pointer);
	switch(buf) {
	default:
		for(i = 0;i < NKEYS;i++) {
			if(!memcmp(&file_buf[tmp_file_pointer], Keytab[i].name, token_len = lexer_get_token_len(tmp_file_pointer)))
				break;
		}
		tmp_file_pointer = lexer_get_next_pointer(tmp_file_pointer, token_len);
		if(i == NKEYS) {
			if(string)
				*string = &file_buf[tmp_file_pointer];
			if(len)
				*len = token_len;
			ret = IDENTIFIER;
		} else
			ret = i;
		break;
	case 0:
		ret = BADTOK;
	}
out:
	now_file_pointer = tmp_file_pointer;
	return ret;
}